package server

import (
	"io/ioutil"
	"log"

	"github.com/naoina/toml"
	"github.com/naoina/toml/ast"
)

// CommonConfig ...
type CommonConfig struct {
	Version  string
	IsDebug  bool
	LogLevel string
	LogPath  string
	Hostname string
}

// EtcdConf ...
type EtcdConf struct {
	Addrs      []string
	Dltimeout  int
	ReportTime int
	ReportDir  string
	TTL        int64
}

// SQLConf ...
type SQLConf struct {
	Addr     string
	Port     string
	Database string
	Acc      string
	Pw       string
}

// EchoConf ...
type EchoConf struct {
	Addr string
}

// Config ...
type Config struct {
	Common *CommonConfig
	EtcdC  *EtcdConf
	EchoC  *EchoConf
	SQLC   *SQLConf
}

var Conf *Config

func LoadConfig(file string) {
	// init the new  config params
	Conf = &Config{
		Common: &CommonConfig{},
		EtcdC:  &EtcdConf{},
		EchoC:  &EchoConf{},
		SQLC:   &SQLConf{},
	}

	contents, err := ioutil.ReadFile(file)
	if err != nil {
		log.Fatal("[FATAL] load config: ", err)
	}

	tbl, err := toml.Parse(contents)
	if err != nil {
		log.Fatal("[FATAL] parse config: ", err)
	}

	// parse common config
	parseCommon(tbl)

	// init log logger
	InitLogger(Conf.Common.LogPath, Conf.Common.LogLevel, Conf.Common.IsDebug)

	// parse etcd config
	parseEtcd(tbl)

	parseSQL(tbl)

	parseEcho(tbl)

}

func parseEtcd(tbl *ast.Table) {
	if val, ok := tbl.Fields["etcd"]; ok {
		subTbl, ok := val.(*ast.Table)
		if !ok {
			log.Fatalln("[FATAL] : ", subTbl)
		}
		err := toml.UnmarshalTable(subTbl, Conf.EtcdC)
		if err != nil {
			log.Fatalln("[FATAL] parseEtcd: ", err, subTbl)
		}
	}
}

func parseCommon(tbl *ast.Table) {
	if val, ok := tbl.Fields["common"]; ok {
		subTbl, ok := val.(*ast.Table)
		if !ok {
			log.Fatalln("[FATAL] : ", subTbl)
		}
		err := toml.UnmarshalTable(subTbl, Conf.Common)
		if err != nil {
			log.Fatalln("[FATAL] parseCommon: ", err, subTbl)
		}
	}
}

func parseEcho(tbl *ast.Table) {
	if val, ok := tbl.Fields["echo"]; ok {
		subTbl, ok := val.(*ast.Table)
		if !ok {
			log.Fatalln("[FATAL] : ", subTbl)
		}
		err := toml.UnmarshalTable(subTbl, Conf.EchoC)
		if err != nil {
			log.Fatalln("[FATAL] parseEcho: ", err, subTbl)
		}
	}
}

func parseSQL(tbl *ast.Table) {
	if val, ok := tbl.Fields["sql"]; ok {
		subTbl, ok := val.(*ast.Table)
		if !ok {
			log.Fatalln("[FATAL] : ", subTbl)
		}
		err := toml.UnmarshalTable(subTbl, Conf.SQLC)
		if err != nil {
			log.Fatalln("[FATAL] parseSQL: ", err, subTbl)
		}
	}
}
